《Android 基础(一)》 Service

介绍

Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service有两种状态,“启动的”和“绑定”。

使用方法

看下关于Service两张比较经典的图
这里写图片描述

这里写图片描述

####简单实例
AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<application
android:label="@string/app_name"
android:icon="@drawable/ic_launcher">

<activity
android:name=".MyActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".MyService"
android:enabled="true"/> <!--四大组件都要在AndroidManifest中申明一把 -->
</application>

MyActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MyActivity extends Activity implements View.OnClickListener, ServiceConnection {
public static String TAG = "MyActivity";

Intent intent;

/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Log.e(TAG, "MyActivity OnCreate");
intent = new Intent(MyActivity.this, MyService.class);

findViewById(R.id.bt_startservice).setOnClickListener(this);
findViewById(R.id.bt_stopservice).setOnClickListener(this);
findViewById(R.id.bt_bindservice).setOnClickListener(this);
findViewById(R.id.bt_unbindservice).setOnClickListener(this);
}
//OnClick事件监听
public void onClick(View view) {
Log.e(TAG,"OnClick");
switch (view.getId()) {
case R.id.bt_startservice:
Log.e(TAG, "start Service");
startService(intent);
break;
case R.id.bt_stopservice:
stopService(intent);
break;
case R.id.bt_bindservice:
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.bt_unbindservice:
unbindService(this);
break;
}
}

@Override //binderService成功后回调,带过来的IBinder可用于和Activity通信
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
}

@Override //在服务崩溃或被杀死导致的连接中断时被调用
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected");
}
}

MyService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class MyService extends Service {
public static String TAG = "MyService";

@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "MyService onCreate");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

Log.e(TAG, "onStartCommand");

//用来测试Service是否在后台有运行
/*new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, "Service is Running ...");
}
}
}).start();*/
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy");
}

@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return new Binder();//new一个binder对象通过onServiceConnected回调,方便通信
}

@Override
public boolean onUnbind(Intent intent) {
Log.e(TAG, "onUnbind");
return super.onUnbind(intent);
}

@Override //onRebind的调用时机和onUnbind的返回值有关系
public void onRebind(Intent intent) {
Log.e(TAG, "onRebind");
super.onRebind(intent);
}
}

测试结果

  1. 启动服务,停止服务
    这里写图片描述
  2. 绑定服务,解绑服务
    这里写图片描述
  3. 启动服务,绑定服务,解绑服务
    这里写图片描述
    注意:这里最后Service是没有onDestory的
  4. 启动服务,绑定服务,解绑服务,停止服务
    这里写图片描述

Binder使用,这个很关键

MyService.java中修改

1
2
3
4
5
6
7
8
9
 public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return new MyBinder();
}
class MyBinder extends Binder {
public void sayHello() {
Log.e(TAG,"I am a binder, hi");
}
}

MyActivity.java中修改

1
2
3
4
5
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
MyService.MyBinder binder = (MyService.MyBinder) iBinder;
((MyService.MyBinder) iBinder).sayHello();
}

然后执行:绑定服务,解绑服务
这里写图片描述

通过这个Binder,再加上Callback,可以实现对Service内部状态的监听
先定义一个接口,然后创建get与set,在onBinder方法中定义一个线程不停的发送数据

1
2
3
4
5
6
7
8
9
10
11
12
public interface Callback() {
public void onDateChanged(String data) {
}
}

public void setCallback(Callback callback) {
this.callback = callback;
}

public Callback getCallback() {
return callback;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");

running = true;//running通过service的生命周期控制
new Thread(new Runnable() {
@Override
public void run() {
while (running) {
try {
Thread.sleep(1000);
i++;
String str = "send: " + i ;
callback.onDateChanged(str);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, "Service is Running ... ");
}
}
}).start();
return new MyBinder();
}

然后在MyBinder类中定义一个getService方法

1
2
3
public MyService getSetvice() {
return MyService.this;
}

然后在onServiceConnected中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
MyService.MyBinder binder = (MyService.MyBinder) iBinder;
MyService myservice = binder.getService();
myservice.setCallback(new MyService.Callback() {
@Override
public void onDateChanged(String str) {//非UI线程无法直接更新UI,需要通过handler机制
Message msg = new Message();
msg.arg1 = 1;
Bundle bundle = new Bundle();
bundle.putString("data", str);
msg.setData(bundle);
handler.sendMessage(msg);
}
});
}

通过这种方式就可以实现Service和Activity的通信工作,不难看出,Binder在其中起着非常重要的角色。
Android中进程间通信,从JAVA到C++基本上都是用Binder来实现的,上层使用的AIDL下一篇介绍一下,

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×